home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Collection of Tools & Utilities
/
Collection of Tools and Utilities.iso
/
ansi
/
pcmous13.zip
/
PCMOUSE.ASM
< prev
next >
Wrap
Assembly Source File
|
1994-03-14
|
31KB
|
1,278 lines
comment *
PCMOUSE (c) 1992,1994 by Jürgen G. Weber
Wiesentalstraße 1
D-74523 Schwäbisch Hall
Germany - European Union
ALL RIGHTS RESERVED
CUT and PASTE in Dos Text Mode
Function: Select text while left button is pressed. As soon as
button is released the selected text is copied from
screen into internal buffer. Buffer is cleared not
until the the next selection, but that is also if a
screen area is only clicked at and nothing selected.
MAKE: tasm pcmouse
tlink pcmouse
*
XT equ 0 ; set this to TRUE if you want PCMOUSE to run
; on an old PC
TRUE equ -1
FALSE equ not TRUE
DE_INSTALL equ 2
ACTIVATE equ 3
TICK_TOO equ 4
NOT_INSTALLED equ 40h
ALL_OK equ 41h
WRO_VEC equ 42h
PVERSION equ '1.3'
TIMER_TOO equ TRUE ; decides if at every timer tick
; the keyboard buffer is fed
; but only if also /T
if not XT
.286 ; the times, they're a-changing ... memento mori 808[6|8]
endif
locals ; makes the local @@Label possible
MOUSE_FN equ 80h ; new function of int 16h, that tells, if
; the program is already installed
INST_HND equ 67h ; tell int 16 to reinstall mouse handler
IDENTCODE equ 41751 ; anything, e.g. my phone number
; the bufleng is enough for half of a screen, but often is enough
; for more as blanks are compressed
RD_BUFLEN EQU 1024
; Masks for mouse events
M_MOVED EQU 1
M_LT_PRESSED EQU 10B
M_LT_RELEASD EQU 100B
M_RT_PRESSED EQU 1000B
M_RT_RELEASD EQU 10000B
; mask to XOR the selected screen area with to display it
DEFAULT_SCR_MARK_MASK EQU 01010000b
; maximal time between the clicks of a mouse double click
; in timer ticks
DCLCK_SPEED equ 9
; the following macros make the listing better readable
show_mouse macro
push ax
mov ax,1 ; show mouse
int 33h
pop ax
endm
hide_mouse macro
push ax
mov ax,2 ; hide mouse
int 33h
pop ax
endm
incz macro op ; if Z op++
local not_zero
jnz short not_zero
inc op
not_zero:
endm
movz macro reg,val1,val2 ; reg = ZF ? val1 : val2
local is_zero
ifnb <val1>
mov reg,val1
endif
jz short is_zero
ifnb <val2>
mov reg,val2
endif
is_zero:
endm
pushr macro regs ;; eg: pushr <bx,ax,cx>
local reg
irp reg,<regs>
push reg
endm
endm
popr macro regs ;; eg: popr <cx,ax,bx>
local reg
irp reg,<regs>
pop reg
endm
endm
incr macro reg,count ;; inc(reg,count)
rept count
inc reg
endm
endm
decr macro reg,count ;; dec(reg,count)
rept count
dec reg
endm
endm
if XT
xpusha macro
pushr <AX,BX,CX,DX,BP,SI,DI>
endm
xpopa macro
popr <DI,SI,BP,DX,CX,BX,AX>
endm
else
xpusha macro
pusha
endm
xpopa macro
popa
endm
endif
if XT
biosdata segment at 40h
org 1ah
headptr dw (?) ; pointer to next key entry to read
tailptr dw (?) ; pointer to last read key entry
org 80h
bufstrt dw (?) ; pointer to start keyboard buffer
bufend dw (?) ; pointer to end keyboard buffer
biosdata ends
endif ; XT
code segment
assume cs:code
res_beg equ $ ; keep resident starting from here
tick_flg db FALSE ; stuff at timer ticks too ?
left_press_flg db FALSE ; left button is pressed
select_flag db FALSE ; there is an area marked on screen
mouse_on_flg db FALSE ; mouse is on
ctrl_rt_clck_flg db FALSE ; at the last right click ctrl was pressed, too
in10_flg dw 0 ; is incremented at each call of int 10h
old_mask dw 0 ; is used in Patch of Exec
old_rout dw 0,0 ; also
pressed_scroffs dw (?) ; screen position at mouse click
old_scroffs dw (?) ; screen position befor last mouse movement
scr_mark_mask db DEFAULT_SCR_MARK_MASK
xor_ptr dw (?) ; pointer to scren area to mark
charsave db 0 ; if keyboard buffer full, save char here
colsPline dw (?) ; characters per line on screen
videoseg dw (?) ; segment of screen memory
videooffs dw (?) ; offset of actual video page
lclcktime dw 0,0 ; time since last left click
buffer_valid db FALSE ; becomes true after right click
blnks_left db (?) ; rest of actual blanc coding
buf_poi dw offset rd_buffer ; pointer to char buffer (read from there)
buf_end_poi dw offset rd_buffer
; calculate video offset from x and y
; In: x=cx, y=dx ; x=0.., y=0..
; Out: ax := offs = y*80+x
xy2offs proc
pushr <dx,cx>
if XT
rept 3
shr cx,1
endm
else
shr cx,3
endif
cmp colsPline,40
jnz short @@no_40
shr cx,1 ; divide by 16 if there are 40 columns per line
@@no_40:
if XT
rept 3
shr dx,1
endm
else
shr dx,3
endif
mov ax,dx
mul colsPline
add ax,cx ; +=x
add ax,ax ; 2 bytes per character
add ax,videooffs
inc ax ; -> attribute
popr <cx,dx>
ret
xy2offs endp
; show or hide mark on screen
xor_scr proc
pushr <cx,bx,dx>
push ds
hide_mouse ; in order not to destroy the mouse cursor
mov bx,xor_ptr
mov cl,scr_mark_mask
mov dx,videoseg
mov ds,dx
sar ax,1 ; /=2 to get number of characters
or ax,ax
jns short @@pos_loop
; mouse was moved to the left
@@neg_loop:
xor byte ptr [ds:bx],cl ; scr_mark_mask
sub bx,2
inc ax ; inc, as counter is negativ
jnz short @@neg_loop
jmp short @@exit
; mouse was moved to the right
@@pos_loop:
add bx,2
xor byte ptr [ds:bx],cl
dec ax
jnz short @@pos_loop
@@exit:
show_mouse
pop ds
mov xor_ptr,bx
popr <dx,bx,cx>
ret
xor_scr endp
; select single word chosen by double click
select_word proc
push videoseg
pop ds
mov bx,pressed_scroffs ; -> attribute
dec bx
call @@tst_let
jc @@exit ; clicked to void
@@go_left: ; search for word begin
call @@tst_let
decr bx,2
jnc @@go_left
add bx,5 ; points to attribute again
mov pressed_scroffs,bx
decr bx,2
mov xor_ptr,bx
dec bx
@@go_right: ; search for word end
incr bx,2
call @@tst_let
jnc @@go_right
mov ax,bx
inc bx
mov old_scroffs,bx
sbb ax,xor_ptr ; cy is 1 from tst_let
call xor_scr
@@exit:
ret
@@tst_let: ; if [ds:bx] in {0..9,A..Z,a..z,80h..a5h,_}
mov al,[ds:bx] ; cy:=0
cmp al,'0' ; else
jb @@nolet ; cy:=1
cmp al,'9'
jbe @@let ; 0..9
cmp al,'A'
jb @@nolet
cmp al,'Z'
jbe @@let ; A..Z
cmp al,'_'
jz @@let
cmp al,'a'
jb @@nolet
cmp al,'z'
jbe @@let ; a..z
cmp al,80h
jb @@nolet ; european special characters
cmp al,0a5h
jbe @@let
cmp al,0e0h
jb @@nolet ; greek letters
cmp al,0ebh
ja @@nolet
@@let:
clc
ret
@@nolet:
stc
ret
select_word endp
; select screen area that was passed
; during mouse movement
scr_select proc
; In: cx,dx = mouse x,y
call xy2offs
push ax
sub ax,old_scroffs ; ax:= number passed positions * 2
pop old_scroffs ; new pos to old pos
jz short @@exit ; was moved to little to change text pos
call xor_scr
mov select_flag,TRUE
@@exit:
ret
scr_select endp
; deselect screen area that was passed
; during mouse movement
scr_un_select proc
cmp select_flag,TRUE
jnz short @@exit ;